--[[ getfenv ]]
local _G = getfenv(0);
local assert, setmetatable, getmetatable = assert, setmetatable, getmetatable;
local type, date = type, date;
local format = string.format;
local floor = math.floor;

--[[ LibStub and Ace2 ]]
local LibStub = _G["LibStub"];
local AceLibrary = _G["AceLibrary"];

--[[ Make sure everything we need is available ]]
assert(LibStub													, format("Error, EquivalencePoints requires %s", "LibStub"));
assert(LibStub("AceAddon-3.0")					, format("Error, EquivalencePoints requires %s", "AceAddon-3.0"));
assert(LibStub("AceConsole-3.0")				, format("Error, EquivalencePoints requires %s", "AceConsole-3.0"));
assert(LibStub("AceEvent-3.0")					, format("Error, EquivalencePoints requires %s", "AceEvent-3.0"));
assert(LibStub("AceTimer-3.0")					, format("Error, EquivalencePoints requires %s", "AceTimer-3.0"));
assert(LibStub("AceDB-3.0")							, format("Error, EquivalencePoints requires %s", "AceDB-3.0"));
assert(LibStub("AceSerializer-3.0")			, format("Error, EquivalencePoints requires %s", "AceSerializer-3.0"));
assert(LibStub("AceLocale-3.0")					, format("Error, EquivalencePoints requires %s", "AceLocale-3.0"));
assert(AceLibrary												, format("Error, EquivalencePoints requires %s", "Ace2"));
assert(AceLibrary("ItemBonusLib-1.0")		, format("Error, EquivalencePoints requires %s", "ItemBonusLib-1.0"));
assert(AceLibrary("TipHooker-1.0")			, format("Error, EquivalencePoints requires %s", "TipHooker-1.0"));

--[[ Create the AddOn ]]
local AddOn = LibStub("AceAddon-3.0"):NewAddon("EquivalencePoints", "AceConsole-3.0", "AceEvent-3.0", "AceTimer-3.0", "AceComm-3.0");
AddOn.debug = false; -- Always start in non-debugging mode
local L = LibStub("AceLocale-3.0"):GetLocale("EquivalencePoints")

--[[ Create Printer functions (to use print in another file of the addon just do: local print = function(...) AddOn:PrintFunction(...); end) ]]
function AddOn:PrintFunction(...) _G["print"](L["_print"], ...); end
function AddOn:DebugFunction(...) if (AddOn.debug) then _G["print"](format(L["_debug"], date("[%H:%M:%S]")), ...); end end -- date("[%Y-%m-%d %H:%M:%S]")

--[[ Some Colors ]]
AddOn.colors = {
	R = (127 / 255),
	G = (255 / 255),
	B = (212 / 255),
	info = { -- FFDC5F
		R = (255 / 255),
		G = (220 / 255),
		B = (95 / 255),
	},
	critical = {
		R = (226 / 255),
		G = (45 / 255),
		B = (75 / 255),
	},
};

--[[ Some functions we'll use later ]]
function AddOn.table_copy(from, to)
	to = to or {}; -- Destination is either a supplied table or a new table
	
	for key, value in pairs(from) do 
		local newKey = ((type(key) == "table") and AddOn.table_copy(key)) or key;
			
		if (type(value) == "table") then
			to[newKey] = AddOn.table_copy(value);
		else
			to[newKey] = value;
		end
	end
	
	setmetatable(to, getmetatable(from));
	return to;
end

function AddOn.math_round(number, decimals)
	assert(type(number) == "number", "Bad argument #1 to 'round(number, decimals)' (number expected)");
	assert(type(decimals) == "number" or type(decimals) == "nil", "Bad argument #2 to 'round(number, decimals)' (number or nil expected)");
	
  local multiplier = (10^(decimals or 0));
  return floor(number * multiplier + 0.5) / multiplier;
end;

-- Returns 1 if version a is outdated, 2 if version b is outdated and 0 if equal, Credz to ClosetGnome
function AddOn.VersionCompare(a, b)
  if type(a) == "string" then a = a:trim() end
  if type(b) == "string" then b = b:trim() end
  if a == b then
    return 0
  elseif tonumber(a) and tonumber(b) then
    if tonumber(a) == tonumber(b) then
      return 0
    else
      return tonumber(b) > tonumber(a) and 1 or 2
    end
  else
    a = tostring(a):trim()
    b = tostring(b):trim()
    local numA = a:gsub("%D", "")
    local numB = b:gsub("%D", "")
    numA = tonumber(numA)
    numB = tonumber(numB)
    if type(numA) == "number" and type(numB) == "number" then
      if numA == numB then
        return 0
      else
        return numB > numA and 1 or 2
      end
    else
      if numB and not numA then
        return 1
      else
        return 2
      end
    end
  end
end -- VersionCompare("2.2", "2.1"); == 2